from lxml import etree
import requests
from bs4 import BeautifulSoup
import json
import datetime
import pandas as pd
from dateutil.relativedelta import relativedelta
from rservice import *

headers = {
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
}

city_code = "101221501"


# 获取当天天气
def get_weather_day(url=f"https://www.weather.com.cn/weather1d/101221501.shtml"):
    daytime = {}
    night = {}
    # 访问天气网
    response = requests.get(url, headers=headers)

    response.raise_for_status()
    response.encoding = response.apparent_encoding

    # 解析网页
    html = etree.HTML(response.text)

    clearfix = html.xpath("//ul[@class='clearfix']")[0]
    for li in clearfix.xpath("li"):
        title = "|".join(li.xpath("h1/text()"))
        wea = "|".join(li.xpath("p[@class='wea']/text()"))  # 天气状态
        tem = "|".join(li.xpath("p[@class='tem']/span/text()"))  # 温度
        win = "|".join(li.xpath("p[@class='win']/span/text()"))  # 风级
        if "白天" in title:
            daytime = {
                'title': title, 'weather': wea, 'temp': tem, 'wind_scale': win
            }
        else:
            night = {
                'title': title, 'weather': wea, 'temp': tem, 'wind_scale': win
            }

    return {'daytime': daytime, 'night': night}


# 获取24小时天气状态
def get_weather_hour(url="https://www.weather.com.cn/weather1d/101221501.shtml"):
    r = requests.get(url, timeout=30, headers=headers)
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    day1_html = r.text
    # data = pd.DataFrame(columns=['时间', '温度', '风力方向', '风级', '降水量', '相对湿度', '空气质量'],
    #                     data=None)
    data = pd.DataFrame(columns=['date', 'temp', 'direction', 'wind_scale', 'precipitation', 'humidity', 'quality'],
                        data=None)
    bs = BeautifulSoup(day1_html, "html.parser")  # 创建BeautifulSoup对象
    body = bs.body
    data2 = body.find_all('div', {'class': 'left-div'})
    text = data2[1].find('script').string
    text = text[text.index('=') + 1:-2]  # 移除改var data=将其变为json数据
    jd = json.loads(text)
    dayone = jd['od']['od2']  # 找到当天的数据
    dayone = dayone[1:]
    hour = dayone[0]['od21']
    for i in dayone:
        if (i['od21'] <= hour):
            time = datetime.datetime.now() + datetime.timedelta(days=1)
            day = time.strftime('%Y-%m-%d')
        else:
            time = datetime.datetime.now()
            day = time.strftime('%Y-%m-%d')
        temp = []
        temp.append(f"{day} {i['od21']}:00:00")  # 添加时间
        temp.append(float(i['od22']))  # 添加当前时刻温度
        temp.append(i['od24'])  # 添加当前时刻风力方向
        temp.append(int(i['od25']))  # 添加当前时刻风级
        temp.append(int(i['od26']))  # 添加当前时刻降水量
        temp.append(int(i['od27']))  # 添加当前时刻相对湿度
        temp.append(i['od28'])  # 添加当前时刻控制质量
        data.loc[len(data)] = temp

    data.sort_values(by="date", ascending=True, inplace=True)

    data['fire_warning'] = data.apply(hour_forest_fire_warning, axis=1)
    data['flood_warning'] = data.apply(hour_flood_warning, axis=1)
    data['cold_warning'] = data.apply(hour_cold_warning, axis=1)
    data['wind_warning'] = data.apply(hour_wind_warning, axis=1)

    data['fire_warning_decision'] = data.apply(hour_forest_fire_warning_decision, axis=1)
    data['flood_warning_decision'] = data.apply(hour_forest_flood_warning_decision, axis=1)
    data['cold_warning_decision'] = data.apply(hour_forest_cold_warning_decision, axis=1)
    data['wind_warning_decision'] = data.apply(hour_forest_wind_warning_decision, axis=1)

    return data


# 最近7天的天气状态
def get_weather_day7(url='https://www.weather.com.cn/weather/101221501.shtml'):
    r = requests.get(url, timeout=30, headers=headers)
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    html = r.text

    """处理得到有用信息保存数据文件"""
    weather_day7_data = pd.DataFrame(
        columns=['day', 'weather', 'min_temp', 'max_temp', 'direction1', 'direction2', 'wind_scale'],
        data=None)
    bs = BeautifulSoup(html, "html.parser")  # 创建BeautifulSoup对象
    body = bs.body
    data = body.find('div', {'id': '7d'})  # 找到div标签且id = 7d
    # 下面爬取7天的数据
    ul = data.find('ul')  # 找到所有的ul标签
    li = ul.find_all('li')  # 找到左右的li标签
    i = 0  # 控制爬取的天数
    for day in li:  # 遍历找到的每一个li
        if 0 < i < 7:
            temp = []  # 临时存放每天的数据
            date = day.find('h1').string  # 得到日期
            date = date[0:date.index('日')]  # 取出日期号
            temp.append(date)
            inf = day.find_all('p')  # 找出li下面的p标签,提取第一个p标签的值，即天气
            temp.append(inf[0].string)

            tem_low = inf[1].find('i').string  # 找到最低气温

            if inf[1].find('span') is None:  # 天气预报可能没有最高气温
                tem_high = None
            else:
                tem_high = inf[1].find('span').string  # 找到最高气温
            temp.append(int(tem_low[:-1]))
            if tem_high[-1] == '℃':
                temp.append(int(tem_high[:-1]))
            else:
                temp.append(int(tem_high))

            wind = inf[2].find_all('span')  # 找到风向
            for j in wind:
                temp.append(j['title'])

            wind_scale = inf[2].find('i').string  # 找到风级
            index1 = wind_scale.index('级')
            temp.append(int(wind_scale[index1 - 1:index1]))
            weather_day7_data.loc[len(weather_day7_data)] = temp
        i = i + 1
    return weather_day7_data


def get_weather_day15(url='https://www.weather.com.cn/weather15d/101221501.shtml'):
    r = requests.get(url, timeout=30, headers=headers)
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    html = r.text

    """处理得到有用信息保存数据文件"""
    weather_day15_data = pd.DataFrame(
        columns=['day', 'weather', 'min_temp', 'max_temp', 'direction1', 'direction2', 'wind_scale'],
        data=None)
    bs = BeautifulSoup(html, "html.parser")  # 创建BeautifulSoup对象
    body = bs.body
    data = body.find('div', {'id': '15d'})  # 找到div标签且id = 15d
    ul = data.find('ul')  # 找到所有的ul标签
    li = ul.find_all('li')  # 找到左右的li标签
    i = 0  # 控制爬取的天数
    for day in li:  # 遍历找到的每一个li
        if i < 8:
            temp = []  # 临时存放每天的数据
            date = day.find('span', {'class': 'time'}).string  # 得到日期
            date = date[date.index('（') + 1:-2]  # 取出日期号
            temp.append(date)
            weather = day.find('span', {'class': 'wea'}).string  # 找到天气
            temp.append(weather)
            tem = day.find('span', {'class': 'tem'}).text  # 找到温度
            temp.append(int(tem[tem.index('/') + 1:-1]))  # 找到最低气温
            temp.append(int(tem[:tem.index('/') - 1]))  # 找到最高气温
            wind = day.find('span', {'class': 'wind'}).string  # 找到风向
            if '转' in wind:  # 如果有风向变化
                temp.append(wind[:wind.index('转')])
                temp.append(wind[wind.index('转') + 1:])
            else:  # 如果没有风向变化，前后风向一致
                temp.append(wind)
                temp.append(wind)
            wind_scale = day.find('span', {'class': 'wind1'}).string  # 找到风级
            index1 = wind_scale.index('级')
            temp.append(int(wind_scale[index1 - 1:index1]))

            weather_day15_data.loc[len(weather_day15_data)] = temp
    return weather_day15_data


def add_year_month(weather_days):
    time = datetime.datetime.now()
    today = time.strftime('%d')
    same_month = time.strftime('%Y-%m')
    next_month = datetime.datetime.now() + relativedelta(months=1)
    next_month = next_month.strftime('%Y-%m')

    weather_days["day"] = weather_days["day"].apply(
        lambda day: f"0{day}" if int(day) < 10 else f"{day}")

    weather_days["day"] = weather_days["day"].apply(
        lambda day: f"{same_month}-{day}" if day >= today else f"{next_month}-{day}")

    return weather_days


#
def get_weather_days():
    weather_day7 = get_weather_day7()
    weather_day15 = get_weather_day15()

    # 合并最近7天和最近15天
    weather_days = pd.concat([weather_day7, weather_day15], axis=0)

    # 增加年月
    weather_days = add_year_month(weather_days)

    weather_days['fire_warning'] = weather_days.apply(days_forest_fire_warning, axis=1)
    weather_days['flood_warning'] = weather_days.apply(days_flood_warning, axis=1)

    return weather_days.head(7)


# 获取实时温度
def get_weather_real_time():
    weather_hour = get_weather_hour()
    time = datetime.datetime.now()
    curr_hour = time.strftime('%Y-%m-%d %H:00:00')
    df = weather_hour[weather_hour["date"] == curr_hour]
    last = df.iloc[-1]
    # 将上述对象转为字典dict
    dict = last.to_dict()
    return dict


if __name__ == '__main__':
    # weather_day = get_weather_day()
    # print(weather_day)
    #
    weather_hour = get_weather_hour()
    weather_days = get_weather_days()
    # weather_real_time = get_weather_real_time()
    # print(weather_real_time)

    # # curr_day.to_csv("curr_day.csv", index=False)
    # weather_hour.to_csv("weather_hour.csv", index=False)
    # weather_days.to_csv("weather_days_data.csv", index=False)

    print(weather_days)
